package com.github.llyb120.qiuyasql.core;

import com.github.llyb120.qiuyasql.entity.FieldType;
import com.github.llyb120.qiuyasql.entity.TableEntity;
import com.github.llyb120.qiuyasql.entity.TableField;
import lombok.var;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Collection;

/**
 * @Author: Administrator
 * @Date: 2020/10/4 16:23
 */
public class ReflectUtil {

    /**
     * 分析一个类
     *
     * @param clz
     * @return
     */
    public static TableEntity analyze(Class<?> clz){
        QTable qtable = (QTable) clz.getAnnotation(QTable.class);
        if (qtable == null) {
            return null;
        }
        TableEntity entity = new TableEntity();
        entity.setTable(qtable.value());
        for (Field field : clz.getDeclaredFields()) {
            var name = field.getName();
            Class<?> type = field.getType();
            field.setAccessible(true);
            if(Collection.class.isAssignableFrom(type)){
                var gtype = getListGenericType(field);
                if (gtype == null) {
                    continue;
                }
            } else {
                if(CharSequence.class.isAssignableFrom(type)){
                    //string
                    entity.put(name, new TableField(FieldType.STRING, field, name));
                } else if(BigDecimal.class.isAssignableFrom(type)){
                    entity.put(name, new TableField(FieldType.DECIMAL, field, name));
                }
            }
        }
        return entity;
    }


    /**
     * 得到list的范型
     *
     * @param field
     * @return
     */
    private static Type getListGenericType(Field field){
        Type genericType = field.getGenericType();
        if (null == genericType) {
            return null;
        }
        if (genericType instanceof ParameterizedType) {
            ParameterizedType pt = (ParameterizedType) genericType;
            // 得到泛型里的class类型对象
            Class<?> actualTypeArgument = (Class<?>) pt.getActualTypeArguments()[0];
            return actualTypeArgument;
        }
        return null;
    }
}
